using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace GameSystems
{
    /// <summary>
    /// 用户行为分析系统 - 收集和分析用户行为数据
    /// </summary>
    public class UserBehaviorAnalytics : MonoBehaviour
    {
        #region Enums

        /// <summary>
        /// 事件类型
        /// </summary>
        public enum EventType
        {
            Login,
            Logout,
            SessionStart,
            SessionEnd,
            Purchase,
            LevelUp,
            Achievement,
            Custom
        }

        /// <summary>
        /// 用户留存类型
        /// </summary>
        public enum RetentionType
        {
            Daily,
            Weekly,
            Monthly
        }

        #endregion

        #region Data Classes

        /// <summary>
        /// 用户行为事件
        /// </summary>
        [Serializable]
        public class UserEvent
        {
            public string id;
            public string userId;
            public EventType eventType;
            public string eventName;
            public DateTime timestamp;
            public float duration;
            public Dictionary<string, object> parameters;
            public string sessionId;

            public UserEvent()
            {
                id = Guid.NewGuid().ToString();
                timestamp = DateTime.Now;
                parameters = new Dictionary<string, object>();
            }
        }

        /// <summary>
        /// 用户会话信息
        /// </summary>
        [Serializable]
        public class UserSession
        {
            public string id;
            public string userId;
            public DateTime startTime;
            public DateTime endTime;
            public float duration;
            public int eventCount;
            public string deviceInfo;
            public string appVersion;

            public UserSession(string userId)
            {
                id = Guid.NewGuid().ToString();
                this.userId = userId;
                startTime = DateTime.Now;
                deviceInfo = SystemInfo.deviceName;
                appVersion = Application.version;
            }

            public void EndSession()
            {
                endTime = DateTime.Now;
                duration = (float)(endTime - startTime).TotalSeconds;
            }
        }

        /// <summary>
        /// 用户留存数据
        /// </summary>
        [Serializable]
        public class UserRetention
        {
            public string userId;
            public DateTime firstLoginDate;
            public DateTime lastLoginDate;
            public int totalLoginDays;
            public int consecutiveLoginDays;
            public Dictionary<RetentionType, bool> retentionFlags;

            public UserRetention()
            {
                retentionFlags = new Dictionary<RetentionType, bool>();
                totalLoginDays = 0;
                consecutiveLoginDays = 0;
            }
        }

        #endregion

        #region Events

        /// <summary>
        /// 事件记录完成事件
        /// </summary>
        [Serializable] public class EventRecordedEvent : UnityEvent<UserEvent> { }

        /// <summary>
        /// 会话结束事件
        /// </summary>
        [Serializable] public class SessionEndedEvent : UnityEvent<UserSession> { }

        /// <summary>
        /// 数据同步完成事件
        /// </summary>
        [Serializable] public class DataSyncedEvent : UnityEvent { }

        #endregion

        #region Serialized Fields

        [Header("分析配置")]
        [Tooltip("是否启用用户行为分析")]
        [SerializeField] private bool enableAnalytics = true;

        [Tooltip("数据同步间隔（秒）")]
        [SerializeField] private float syncInterval = 300f; // 5分钟

        [Tooltip("最大缓存事件数量")]
        [SerializeField] private int maxCachedEvents = 1000;

        [Tooltip("是否自动同步数据")]
        [SerializeField] private bool autoSyncData = true;

        [Tooltip("是否启用实时分析")]
        [SerializeField] private bool enableRealTimeAnalysis = true;

        [Header("性能监控")]
        [Tooltip("是否启用性能监控")]
        [SerializeField] private bool enablePerformanceMonitoring = false;

        [Tooltip("帧率采样间隔（秒）")]
        [SerializeField] private float frameRateSampleInterval = 1f;

        [Tooltip("内存采样间隔（秒）")]
        [SerializeField] private float memorySampleInterval = 5f;

        [Header("调试选项")]
        [Tooltip("是否启用调试日志")]
        [SerializeField] private bool enableDebugLogs = true;

        [Tooltip("是否在编辑器中启用")]
        [SerializeField] private bool enableInEditor = false;

        #endregion

        #region Events

        [Header("事件回调")]
        [Tooltip("事件记录完成时触发")]
        public EventRecordedEvent OnEventRecorded;

        [Tooltip("会话结束时触发")]
        public SessionEndedEvent OnSessionEnded;

        [Tooltip("数据同步完成时触发")]
        public DataSyncedEvent OnDataSynced;

        #endregion

        #region Private Fields

        private List<UserEvent> cachedEvents = new List<UserEvent>();
        private UserSession currentSession;
        private UserRetention userRetention;
        private string currentUserId;
        private Coroutine syncCoroutine;
        private Coroutine performanceCoroutine;
        private Coroutine frameRateCoroutine;
        private Coroutine memoryCoroutine;

        // 性能数据
        private List<float> frameRateSamples = new List<float>();
        private List<long> memorySamples = new List<long>();

        // 本地存储键
        private const string UserDataKey = "UserAnalyticsData";
        private const string SessionDataKey = "UserSessionData";
        private const string RetentionDataKey = "UserRetentionData";

        #endregion

        #region Unity Lifecycle

        /// <summary>
        /// 初始化组件
        /// </summary>
        private void Awake()
        {
            if (!enableAnalytics || (!enableInEditor && Application.isEditor))
            {
                enabled = false;
                return;
            }

            LoadUserData();
        }

        /// <summary>
        /// 启动时的初始化
        /// </summary>
        private void Start()
        {
            if (autoSyncData)
            {
                StartDataSyncCoroutine();
            }

            if (enablePerformanceMonitoring)
            {
                StartPerformanceMonitoring();
            }
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        private void OnDestroy()
        {
            EndCurrentSession();
            CleanupCoroutines();
            SaveUserData();
        }

        /// <summary>
        /// 应用暂停时保存数据
        /// </summary>
        private void OnApplicationPause(bool pauseStatus)
        {
            if (pauseStatus)
            {
                EndCurrentSession();
                SaveUserData();
            }
            else
            {
                StartNewSession(currentUserId);
            }
        }

        /// <summary>
        /// 应用退出时保存数据
        /// </summary>
        private void OnApplicationQuit()
        {
            EndCurrentSession();
            SaveUserData();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 设置当前用户
        /// </summary>
        /// <param name="userId">用户ID</param>
        public void SetCurrentUser(string userId)
        {
            if (string.IsNullOrEmpty(userId))
            {
                LogError("用户ID不能为空");
                return;
            }

            // 如果用户改变，结束当前会话
            if (currentUserId != userId && currentSession != null)
            {
                EndCurrentSession();
            }

            currentUserId = userId;
            LoadUserRetentionData();

            // 开始新会话
            StartNewSession(userId);
        }

        /// <summary>
        /// 记录用户事件
        /// </summary>
        /// <param name="eventType">事件类型</param>
        /// <param name="eventName">事件名称</param>
        /// <param name="parameters">事件参数</param>
        public void RecordEvent(EventType eventType, string eventName, Dictionary<string, object> parameters = null)
        {
            if (!enableAnalytics || currentSession == null)
                return;

            var userEvent = new UserEvent
            {
                userId = currentUserId,
                eventType = eventType,
                eventName = eventName,
                sessionId = currentSession.id
            };

            if (parameters != null)
            {
                userEvent.parameters = parameters;
            }

            // 添加特殊参数
            userEvent.parameters["timestamp"] = userEvent.timestamp.ToString("yyyy-MM-dd HH:mm:ss");
            userEvent.parameters["device_type"] = SystemInfo.deviceType.ToString();
            userEvent.parameters["platform"] = Application.platform.ToString();

            cachedEvents.Add(userEvent);
            currentSession.eventCount++;

            // 检查缓存大小
            if (cachedEvents.Count > maxCachedEvents)
            {
                cachedEvents.RemoveAt(0);
            }

            // 实时分析
            if (enableRealTimeAnalysis)
            {
                AnalyzeEvent(userEvent);
            }

            OnEventRecorded?.Invoke(userEvent);
            LogDebug($"记录事件: {eventName} ({eventType})");
        }

        /// <summary>
        /// 记录登录事件
        /// </summary>
        public void RecordLoginEvent()
        {
            RecordEvent(EventType.Login, "UserLogin", new Dictionary<string, object>
            {
                ["login_method"] = "standard",
                ["login_time"] = DateTime.Now.ToString("HH:mm:ss")
            });

            UpdateUserRetention();
        }

        /// <summary>
        /// 记录登出事件
        /// </summary>
        public void RecordLogoutEvent()
        {
            RecordEvent(EventType.Logout, "UserLogout", new Dictionary<string, object>
            {
                ["session_duration"] = currentSession?.duration ?? 0f
            });
        }

        /// <summary>
        /// 记录购买事件
        /// </summary>
        /// <param name="itemId">物品ID</param>
        /// <param name="itemName">物品名称</param>
        /// <param name="price">价格</param>
        /// <param name="currency">货币类型</param>
        public void RecordPurchaseEvent(string itemId, string itemName, float price, string currency = "USD")
        {
            RecordEvent(EventType.Purchase, "ItemPurchase", new Dictionary<string, object>
            {
                ["item_id"] = itemId,
                ["item_name"] = itemName,
                ["price"] = price,
                ["currency"] = currency
            });
        }

        /// <summary>
        /// 记录升级事件
        /// </summary>
        /// <param name="oldLevel">旧等级</param>
        /// <param name="newLevel">新等级</param>
        public void RecordLevelUpEvent(int oldLevel, int newLevel)
        {
            RecordEvent(EventType.LevelUp, "PlayerLevelUp", new Dictionary<string, object>
            {
                ["old_level"] = oldLevel,
                ["new_level"] = newLevel
            });
        }

        /// <summary>
        /// 记录成就事件
        /// </summary>
        /// <param name="achievementId">成就ID</param>
        /// <param name="achievementName">成就名称</param>
        public void RecordAchievementEvent(string achievementId, string achievementName)
        {
            RecordEvent(EventType.Achievement, "AchievementUnlocked", new Dictionary<string, object>
            {
                ["achievement_id"] = achievementId,
                ["achievement_name"] = achievementName
            });
        }

        /// <summary>
        /// 获取用户会话信息
        /// </summary>
        /// <returns>当前会话信息</returns>
        public UserSession GetCurrentSession()
        {
            return currentSession;
        }

        /// <summary>
        /// 获取用户留存数据
        /// </summary>
        /// <returns>用户留存信息</returns>
        public UserRetention GetUserRetention()
        {
            return userRetention;
        }

        /// <summary>
        /// 获取事件统计
        /// </summary>
        /// <param name="eventType">事件类型</param>
        /// <returns>事件数量</returns>
        public int GetEventCount(EventType eventType)
        {
            int count = 0;
            foreach (var evt in cachedEvents)
            {
                if (evt.eventType == eventType)
                {
                    count++;
                }
            }
            return count;
        }

        /// <summary>
        /// 同步数据到服务器
        /// </summary>
        public void SyncDataToServer()
        {
            if (!enableAnalytics || cachedEvents.Count == 0)
                return;

            StartCoroutine(SyncDataCoroutine());
        }

        /// <summary>
        /// 清除所有分析数据
        /// </summary>
        public void ClearAllData()
        {
            cachedEvents.Clear();
            currentSession = null;
            userRetention = null;
            frameRateSamples.Clear();
            memorySamples.Clear();

            PlayerPrefs.DeleteKey(UserDataKey);
            PlayerPrefs.DeleteKey(SessionDataKey);
            PlayerPrefs.DeleteKey(RetentionDataKey);

            LogDebug("已清除所有分析数据");
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 开始新会话
        /// </summary>
        private void StartNewSession(string userId)
        {
            if (currentSession != null)
            {
                EndCurrentSession();
            }

            currentSession = new UserSession(userId);
            RecordEvent(EventType.SessionStart, "SessionStart");

            LogDebug($"开始新会话: {currentSession.id}");
        }

        /// <summary>
        /// 结束当前会话
        /// </summary>
        private void EndCurrentSession()
        {
            if (currentSession == null)
                return;

            currentSession.EndSession();
            RecordEvent(EventType.SessionEnd, "SessionEnd", new Dictionary<string, object>
            {
                ["session_duration"] = currentSession.duration,
                ["event_count"] = currentSession.eventCount
            });

            OnSessionEnded?.Invoke(currentSession);
            LogDebug($"结束会话: {currentSession.id}, 持续时间: {currentSession.duration:F2}秒");

            currentSession = null;
        }

        /// <summary>
        /// 更新用户留存数据
        /// </summary>
        private void UpdateUserRetention()
        {
            if (userRetention == null)
            {
                userRetention = new UserRetention
                {
                    userId = currentUserId,
                    firstLoginDate = DateTime.Now
                };
            }

            userRetention.lastLoginDate = DateTime.Now;

            // 计算登录天数
            var daysSinceFirstLogin = (DateTime.Now - userRetention.firstLoginDate).Days;
            if (daysSinceFirstLogin == 0)
            {
                userRetention.totalLoginDays = 1;
                userRetention.consecutiveLoginDays = 1;
            }
            else
            {
                // 简化的连续登录计算
                if (DateTime.Now.Date == userRetention.lastLoginDate.Date.AddDays(-1))
                {
                    userRetention.consecutiveLoginDays++;
                }
                else
                {
                    userRetention.consecutiveLoginDays = 1;
                }

                userRetention.totalLoginDays++;
            }

            // 更新留存标志
            UpdateRetentionFlags();
            SaveUserRetentionData();
        }

        /// <summary>
        /// 更新留存标志
        /// </summary>
        private void UpdateRetentionFlags()
        {
            if (userRetention == null)
                return;

            var daysSinceFirstLogin = (DateTime.Now - userRetention.firstLoginDate).Days;

            // 日留存
            userRetention.retentionFlags[RetentionType.Daily] = daysSinceFirstLogin >= 1;

            // 周留存
            userRetention.retentionFlags[RetentionType.Weekly] = daysSinceFirstLogin >= 7;

            // 月留存
            userRetention.retentionFlags[RetentionType.Monthly] = daysSinceFirstLogin >= 30;
        }

        /// <summary>
        /// 实时分析事件
        /// </summary>
        private void AnalyzeEvent(UserEvent userEvent)
        {
            // 这里可以实现实时分析逻辑
            // 例如：检测异常行为、计算实时指标等

            switch (userEvent.eventType)
            {
                case EventType.Purchase:
                    AnalyzePurchaseBehavior(userEvent);
                    break;
                case EventType.LevelUp:
                    AnalyzeLevelProgression(userEvent);
                    break;
                case EventType.Achievement:
                    AnalyzeAchievementBehavior(userEvent);
                    break;
            }
        }

        /// <summary>
        /// 分析购买行为
        /// </summary>
        private void AnalyzePurchaseBehavior(UserEvent userEvent)
        {
            // 分析购买行为模式
            LogDebug($"分析购买行为: {userEvent.parameters.GetValueOrDefault("item_name", "Unknown")}");
        }

        /// <summary>
        /// 分析等级进度
        /// </summary>
        private void AnalyzeLevelProgression(UserEvent userEvent)
        {
            // 分析等级进度模式
            LogDebug($"分析等级进度: {userEvent.parameters.GetValueOrDefault("new_level", 0)}");
        }

        /// <summary>
        /// 分析成就行为
        /// </summary>
        private void AnalyzeAchievementBehavior(UserEvent userEvent)
        {
            // 分析成就获取模式
            LogDebug($"分析成就行为: {userEvent.parameters.GetValueOrDefault("achievement_name", "Unknown")}");
        }

        /// <summary>
        /// 启动数据同步协程
        /// </summary>
        private void StartDataSyncCoroutine()
        {
            if (syncCoroutine != null)
            {
                StopCoroutine(syncCoroutine);
            }

            syncCoroutine = StartCoroutine(DataSyncCoroutine());
        }

        /// <summary>
        /// 数据同步协程
        /// </summary>
        private IEnumerator DataSyncCoroutine()
        {
            while (true)
            {
                yield return new WaitForSeconds(syncInterval);

                if (cachedEvents.Count > 0)
                {
                    yield return StartCoroutine(SyncDataCoroutine());
                }
            }
        }

        /// <summary>
        /// 同步数据协程
        /// </summary>
        private IEnumerator SyncDataCoroutine()
        {
            LogDebug($"开始同步 {cachedEvents.Count} 个事件到服务器");

            // 实际项目中，这里应该调用服务器API
            // 模拟网络延迟
            yield return new WaitForSeconds(2f);

            // 模拟同步成功
            cachedEvents.Clear();
            SaveUserData();

            OnDataSynced?.Invoke();
            LogDebug("数据同步完成");
        }

        /// <summary>
        /// 启动性能监控
        /// </summary>
        private void StartPerformanceMonitoring()
        {
            if (frameRateCoroutine != null)
            {
                StopCoroutine(frameRateCoroutine);
            }

            if (memoryCoroutine != null)
            {
                StopCoroutine(memoryCoroutine);
            }

            frameRateCoroutine = StartCoroutine(FrameRateMonitorCoroutine());
            memoryCoroutine = StartCoroutine(MemoryMonitorCoroutine());
        }

        /// <summary>
        /// 帧率监控协程
        /// </summary>
        private IEnumerator FrameRateMonitorCoroutine()
        {
            while (true)
            {
                yield return new WaitForSeconds(frameRateSampleInterval);
                frameRateSamples.Add(1f / Time.unscaledDeltaTime);

                // 保持最近的100个样本
                if (frameRateSamples.Count > 100)
                {
                    frameRateSamples.RemoveAt(0);
                }
            }
        }

        /// <summary>
        /// 内存监控协程
        /// </summary>
        private IEnumerator MemoryMonitorCoroutine()
        {
            while (true)
            {
                yield return new WaitForSeconds(memorySampleInterval);
                memorySamples.Add(GC.GetTotalMemory(false));

                // 保持最近的100个样本
                if (memorySamples.Count > 100)
                {
                    memorySamples.RemoveAt(0);
                }
            }
        }

        /// <summary>
        /// 加载用户数据
        /// </summary>
        private void LoadUserData()
        {
            if (PlayerPrefs.HasKey(UserDataKey))
            {
                try
                {
                    string jsonData = PlayerPrefs.GetString(UserDataKey);
                    var analyticsData = JsonUtility.FromJson<UserAnalyticsData>(jsonData);

                    if (analyticsData != null && analyticsData.events != null)
                    {
                        cachedEvents = analyticsData.events;
                        LogDebug($"已加载 {cachedEvents.Count} 个缓存事件");
                    }
                }
                catch (Exception e)
                {
                    LogError($"加载用户分析数据失败: {e.Message}");
                }
            }
        }

        /// <summary>
        /// 保存用户数据
        /// </summary>
        private void SaveUserData()
        {
            try
            {
                var analyticsData = new UserAnalyticsData
                {
                    events = cachedEvents,
                    lastUpdated = DateTime.Now
                };

                string jsonData = JsonUtility.ToJson(analyticsData, true);
                PlayerPrefs.SetString(UserDataKey, jsonData);
                PlayerPrefs.Save();
            }
            catch (Exception e)
            {
                LogError($"保存用户分析数据失败: {e.Message}");
            }
        }

        /// <summary>
        /// 加载用户留存数据
        /// </summary>
        private void LoadUserRetentionData()
        {
            if (string.IsNullOrEmpty(currentUserId))
                return;

            string key = RetentionDataKey + currentUserId;
            if (PlayerPrefs.HasKey(key))
            {
                try
                {
                    string jsonData = PlayerPrefs.GetString(key);
                    userRetention = JsonUtility.FromJson<UserRetention>(jsonData);
                    LogDebug($"已加载用户留存数据: {currentUserId}");
                }
                catch (Exception e)
                {
                    LogError($"加载用户留存数据失败: {e.Message}");
                }
            }
        }

        /// <summary>
        /// 保存用户留存数据
        /// </summary>
        private void SaveUserRetentionData()
        {
            if (userRetention == null || string.IsNullOrEmpty(currentUserId))
                return;

            try
            {
                string key = RetentionDataKey + currentUserId;
                string jsonData = JsonUtility.ToJson(userRetention, true);
                PlayerPrefs.SetString(key, jsonData);
                PlayerPrefs.Save();
            }
            catch (Exception e)
            {
                LogError($"保存用户留存数据失败: {e.Message}");
            }
        }

        /// <summary>
        /// 清理协程
        /// </summary>
        private void CleanupCoroutines()
        {
            if (syncCoroutine != null)
            {
                StopCoroutine(syncCoroutine);
                syncCoroutine = null;
            }

            if (performanceCoroutine != null)
            {
                StopCoroutine(performanceCoroutine);
                performanceCoroutine = null;
            }

            if (frameRateCoroutine != null)
            {
                StopCoroutine(frameRateCoroutine);
                frameRateCoroutine = null;
            }

            if (memoryCoroutine != null)
            {
                StopCoroutine(memoryCoroutine);
                memoryCoroutine = null;
            }
        }

        #endregion

        #region Debug Methods

        /// <summary>
        /// 调试日志
        /// </summary>
        private void LogDebug(string message)
        {
            if (enableDebugLogs)
                Debug.Log($"[UserBehaviorAnalytics] {message}");
        }

        /// <summary>
        /// 警告日志
        /// </summary>
        private void LogWarning(string message)
        {
            if (enableDebugLogs)
                Debug.LogWarning($"[UserBehaviorAnalytics] {message}");
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        private void LogError(string message)
        {
            if (enableDebugLogs)
                Debug.LogError($"[UserBehaviorAnalytics] {message}");
        }

        #endregion

        #region Data Structures

        /// <summary>
        /// 用户分析数据
        /// </summary>
        [Serializable]
        private class UserAnalyticsData
        {
            public List<UserEvent> events;
            public DateTime lastUpdated;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// 是否启用分析
        /// </summary>
        public bool EnableAnalytics
        {
            get => enableAnalytics;
            set => enableAnalytics = value;
        }

        /// <summary>
        /// 当前用户ID
        /// </summary>
        public string CurrentUserId => currentUserId;

        /// <summary>
        /// 缓存事件数量
        /// </summary>
        public int CachedEventCount => cachedEvents.Count;

        /// <summary>
        /// 平均帧率
        /// </summary>
        public float AverageFrameRate
        {
            get
            {
                if (frameRateSamples.Count == 0) return 0f;

                float sum = 0f;
                foreach (var sample in frameRateSamples)
                {
                    sum += sample;
                }
                return sum / frameRateSamples.Count;
            }
        }

        /// <summary>
        /// 平均内存使用量
        /// </summary>
        public long AverageMemoryUsage
        {
            get
            {
                if (memorySamples.Count == 0) return 0L;

                long sum = 0L;
                foreach (var sample in memorySamples)
                {
                    sum += sample;
                }
                return sum / memorySamples.Count;
            }
        }

        #endregion
    }
}
